<?php
/**
 * Created by PhpStorm.
 * User: lhl
 * Date: 2019/9/4
 * Time: 20:27
 * Features: JWT封装
 */

namespace app\common\service;


use Firebase\JWT\ExpiredException;
use Firebase\JWT\JWT;
use Firebase\JWT\SignatureInvalidException;
use think\facade\Config;
use think\facade\Request;

class JwtToken
{
    //响应码
    private static $responseCode = [];

    /**
     * 获取JWT-token
     * @param array $userInfo 用户数据
    */
    public static function getToken($userInfo){
        $config = Config::get('api.jwt');
        $time = time();
        //负载
        $payload =  [
            'iss' => isset($config['iss']) ? $config['iss'] : 'krystal', //签发者
            'iat'=> $time, // 签发时间
            'nbf' => $time + (isset($config['nbf']) ? $config['nbf'] : 0), //在什么时间之后该jwt才可用
            'exp' => $time + (isset($config['exp']) ? $config['exp'] : 7200), //过期时间
            'data' => $userInfo
        ];
        return JWT::encode($payload,$config['key']);
    }

    /**
     * 解密jwt-token
     * @param string $jwt 若不填,则会自动获取请求头中jwt
    */
    public static function decodeToken($str = ''){
        //状态码
        self::$responseCode = ApiHelper::getCode();

        $jwt = empty($str) ? Request::header('accesstoken') : $str;
        if(!$jwt){
            return [
                'code' => self::$responseCode['not_login_error'],
                'msg' => 'TOKEN令牌为空'
            ];
        }
        //时间迂回
        JWT::$leeway = Config::get('api.jwt.leeway',60);
        try{
            $decoded = JWT::decode($jwt, Config::get('api.jwt.key'), ['HS256']);
        }catch (ExpiredException $e){
            return [
                'code' => self::$responseCode['not_login_error'],
                'msg' => 'TOKEN令牌已过期,请重新登录!'
            ];
        }catch (SignatureInvalidException $e){
            return [
                'code' => self::$responseCode['not_login_error'],
                'msg' => 'TOKEN令牌无效,请重新登录!'
            ];
        }catch (\UnexpectedValueException $e){
            return [
                'code' => self::$responseCode['not_login_error'],
                'msg' => 'TOKEN令牌无效,请重新登录!'
            ];
        }
        $decoded = json_decode(json_encode($decoded,JSON_UNESCAPED_UNICODE),true);
        //判断时间是否过期
        if ($decoded['exp'] <time() ) {
            return [
                'code' => self::$responseCode['not_login_error'],
                'msg' => 'TOKEN令牌已过期,请重新登录!'
            ];
        } else {
            return [
                'code' => 200,
                'msg' => '验证成功',
                'data' => $decoded
            ];
        }
    }

    /**
     * 检测jwt-token,获取用户信息
    */
    public static function checkToken(){
        $res = self::decodeToken();
        if($res['code'] != 200){
            header("Content-Type: application/json");
            exit(json_encode($res,JSON_UNESCAPED_UNICODE));
        }
        //返回用户信息
        return $res['data']['data'];
    }
}